#ifndef __FILTER_H__
#define __FILTER_H__


#include <iostream>
#include <cstdlib> 
#include <limits>

#include "Image.H"
#include "IO.H"
#include "Util.H"

using namespace pip;
using namespace std;

template <typename T>
T mymax(T a,T b);
template <typename T>
T mymin(T a,T b);

/*
void apply_allpixel(T (*pf)(T), image<T> &image){};*/
template <typename T>
void getMinMaxImage(const Image<T> &in,
					T &min,
					T &max);

// Convolves input with mask and stores result in output
void filter(
  const pip::Image<float> &input, 
  pip::Image<float> &output, 
  const pip::Image<float> &mask, 
  const pip::BorderInfo &bi = pip::border_mirror);

// Performs a separable convolution. The first dimension is convolved with the first kernel in the vector kernels, and so on.
void filterSeparable(
  const pip::Image<float> &in, 
  pip::Image<float> &out, 
  const std::vector<std::vector<float> > &kernels, 
  const pip::BorderInfo &bi = pip::border_mirror);

void imageconvert(const Image<float> &input,
			   Image<unsigned char> * output);


void imageconvert(const Image<unsigned char> &input,
			   Image<float> *output);

void loadimage(string name,
			   Image<float> &loaded);

void saveimage(string name,
			   Image<float> &save);


// Samples the unnormalized Gaussian for given sigma at integer values
float g0(const int &i, const float &sigma);

// Samples the unnormalized first derivative of the Gaussian for given sigma at integer values
float g1(const int &i, const float &sigma);

// Samples the unnormalized second derivative of the Gaussian for given sigma at integer values
float g2(const int &i, const float &sigma);

// Samples the unnormalized third derivative of the Gaussian for given sigma at integer values
float g3(const int &i, const float &sigma);


#endif